#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <getopt.h>
#include <string.h>

#include "procesadorDeParametros.h"
#include "parser.h"
#include "bubblesort.h"
#include "shellsort.h"

const char* version = "1.0";

void mostrarError(const char* mensaje) {
	printf("Error: %s \n", mensaje);
}

void mostrarVersion(const char* version) {
	printf("Ordenador -- Version: %s \n", version);
}

void imprimirHelp (const char* nombrePrograma)	{
	const char* mensajes_ayuda[] = {
		"   -h,	--help        display this help and exit \n",
		"   -V,	--version     display version information and exit \n",
		"   -b,	--bubble      use the bubblesort algorithm \n",
		"   -s,	--sel         use the shellsort algorithm\n",
		NULL
	};
	printf("%s [OPTIONS] [file...]\n", nombrePrograma);

	unsigned i = 0;
	while (mensajes_ayuda[i] != NULL) {
		printf("%s", mensajes_ayuda[i]);
		++i;
	}
}

void seguirLeyendoParametros(int argc, char** argv, int optind, char** archivos, size_t* sizeArchivos) {
	if (optind < argc) {
		while (optind < argc){
			archivos[(*sizeArchivos)] = argv[optind++];
			(*sizeArchivos)++;
		}
	}

	/*Estado de archivos*/
	printf("Estoy en seguirLeyendoParametros \n");
	printf("Estado de ArchivosAOrdenar: \n");
	size_t i;
	for(i = 0; i < (*sizeArchivos); i++) {
		printf("Archivo %zu : %s \n",i, archivos[i]);
	}
}

void showWords(char** words, int arraysize, char* salida) {
    int i;
    FILE* archivo = fopen(salida, "wt");
    for (i = 0; i < arraysize; i++) {
        fwrite(words[i], sizeof(char), strlen(words[i]), archivo);
        fwrite("\n",1,1,archivo);
    }
    fclose(archivo);
}

void freeWords(char** words, int arraysize) {
    int i;
    for (i = 0; i < arraysize; i++) {
        free(words[i]);
    }
    free(words);
}

void realizarOrdenamiento (char siguiente_opcion, char **archivosAOrdenar, size_t *sizeArchivos)
{
	char** words = NULL;
	int arraysize = 0;

	parsearArchivos(archivosAOrdenar, sizeArchivos, &words, &arraysize);

	if (siguiente_opcion == 'b') {
		bubblesort(words, arraysize);
		showWords(words, arraysize, "bubblesort");
	} else {
		shellsort(words, arraysize);
		showWords(words, arraysize, "shellsort");
	}
	freeWords(words, arraysize);
}

void procesarParametros (int argc, char** argv, char** archivosAOrdenar, size_t* sizeArchivos) {

	const char* nombrePrograma = argv[0];

	/* Una cadena que lista las opciones cortas válidas */
	const char* const op_cortas = "hVb:s:" ;

	/* Una estructura de varios arrays describiendo los valores largos */
	const struct option op_largas[] = {
			{ "help",     no_argument,        NULL,   'h'},
			{ "version",  no_argument,        NULL,   'V'},
			{ "bubble",   required_argument,  NULL,   'b'},
			{ "sel",      required_argument,  NULL,   's'},
			{0,0,0,0}
	};

	int siguiente_opcion = getopt_long (argc, argv, op_cortas, op_largas, NULL);

	if (siguiente_opcion == -1) {
		mostrarError("No se coloco la opcion \n");
		imprimirHelp(nombrePrograma);
	} else {

		switch (siguiente_opcion) {

		case 'h' : /* -h o --help */
			imprimirHelp(nombrePrograma);
			break;

		case 'V' : /* -V o --version */
			mostrarVersion(version);
			break;

		case 'b' : /* -b o --bubble */
		case 's' : /* -s o --sel */
			/* optarg contiene el argumento */
			archivosAOrdenar[(*sizeArchivos)] = optarg;
			(*sizeArchivos)++;
			seguirLeyendoParametros(argc, argv, optind, archivosAOrdenar, sizeArchivos);
			realizarOrdenamiento (siguiente_opcion, archivosAOrdenar, sizeArchivos);
			break;
		default :
			imprimirHelp(nombrePrograma);
			break;
		}
	}
}
